﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using BSDS.Core.Infrastructure.Logging;
using BSDS.Core.Model.Conversion.Configuration;
using BSDS.Core.Model.Data;

namespace BSDS.Core.Model.Conversion.Processing
{
    public static class MergeColumnsProcessor
    {
        private static MergeColumnsConfigurations mergeConfiguration;

        public static void LoadConfiguration(string configFile)
        {
            XmlSerializer sr = new XmlSerializer(typeof(MergeColumnsConfigurations));

            if (File.Exists(configFile))
            {
                using (var f = new FileStream(configFile, FileMode.Open))
                {
                    if (f != null)
                    {
                        mergeConfiguration = sr.Deserialize(f) as MergeColumnsConfigurations;
                    }
                }
            }
            else
            {
                throw new FileNotFoundException("Unable to open the Merge configuration file: " + configFile);
            }
        }

        public static void SaveConfiguration(string configFile)
        {
            XmlSerializer sr = new XmlSerializer(typeof(MergeColumnsConfigurations));

            using (var tr = new StreamWriter(configFile))
            {
                sr.Serialize(tr, mergeConfiguration);
            }
        }

        public static void MergeColumns(this BsdsData data)
        {
            StringBuilder sb = new StringBuilder();
            string mergedValue;

            foreach (var entity in data.Entities)
            {
                foreach (var config in mergeConfiguration.configurations)
                {
                    // TODO: THIS LOGIC IS UNIQUE FOR ONE CLIENT. MAKE THIS GENERIC THIS SOMEHOW OR MAKE IT A SEPARATE OPTION.

                    // Get a string array of values from data for each column that is defined in this configuration.
                    var values = entity.AttributeValues.Where(av => config.columns.Any(col => col == av.AttributeInfo.Name));
                    sb.Clear();
                    var first = true;
                    foreach (var v in values)
                    {
                        if (v.Value == "1")
                        {
                            var li = v.AttributeInfo.Name.LastIndexOf("_");
                            if (!first)
                                sb.Append(mergeConfiguration.separator);
                            sb.Append(v.AttributeInfo.Name.Substring(li+1));
                            first = false;
                        }
                    }

                    // Build a single string of those values separated by the defined separator
                    mergedValue = sb.ToString();

                    // Insert a new entity value
                    entity.InsertAttributeValue(new AttributeValue(new AttributeInfo(config.mergedColumn, "String", false), mergedValue), config.columns[0]);

                    // Remove the old enitity values
                    foreach (var c in config.columns)
                    {
                        entity.RemoveAttributeValue(c);
                    }
                }
            }
        }

        // CODE BELOW IS A MORE STRAIGTFORWARD MERGE

//                    // Get a string array of values from data for each column that is defined in this configuration.
//                    var values = entity.AttributeValues.Where(av => config.columns.Any(col => col == av.AttributeInfo.Name)).Select(x => x.Value);
//
//                    // Build a single string of those values separated by the defined separator
//                    mergedValue = string.Join(mergeConfiguration.separator, values);
//
//                    // Insert a new entity value
//                    entity.InsertAttributeValue(new AttributeValue(new AttributeInfo(config.mergedColumn, "String", false), mergedValue), config.columns[0]);
//
//                    // Remove the old enitity values
//                    foreach (var c in config.columns)
//                    {
//                        entity.RemoveAttributeValue(c);
//                    }


        public static void CreateSampleData()
        {
            mergeConfiguration = new MergeColumnsConfigurations();
            mergeConfiguration.configurations = new MergeColumnsConfiguration[] 
            { 
                new MergeColumnsConfiguration() { mergedColumn = "newColumnName1", columns = new string[3] { "one1", "two1", "three1" }},
                new MergeColumnsConfiguration() { mergedColumn = "newColumnName2", columns = new string[3] { "one2", "two2", "three2" }},
                new MergeColumnsConfiguration() { mergedColumn = "newColumnName3", columns = new string[3] { "one3", "two3", "three3" }}
            };

            SaveConfiguration("SampleMergeColumnsConfiguration.xml");
        }
    }
}
